package com.ilia.slitok;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import com.ilia.util.timer.ITimer;

public class Storage4  implements PolyAlloyStorage{
  LinkedList<PolyAlloy> llist;
  PolyAlloy[] content;
  int size;
  private final PolyAlloyTargetAlloyComparator comparator;
  private final ITimer timer;
  public Storage4(int size, PolyAlloyTargetAlloyComparator comparator, ITimer timer) {
    this.size = size;
    this.comparator = comparator;
    this.timer = timer;
    llist = new LinkedList<PolyAlloy>();
    content = new PolyAlloy[size];
    clear();
  }
  public void add(PolyAlloy pa) {
	timer.startTimer("S4_ADD");
    int id = comparator.distance(pa.box);
    if (id<size){
        if (content[id]!=null) {
        	
            content[id].getAlloys().addAll(pa.getAlloys());
          } else {
            content[id] = pa;
            llist.add(pa);
          }
    }
    timer.stopTimer("S4_ADD");
  }
  public PolyAlloy get(PolyAlloy pa) {
	timer.startTimer("S4_GET");
    int id = comparator.distance(pa.box);
    timer.stopTimer("S4_ADD");
    if (id>=size) return null;
    return content[id];
    
  }
  public void clear() {
	timer.startTimer("S4_CLEAR");
//	content = new PolyAlloy[size];
	Arrays.fill(content, null);
	timer.stopTimer("S4_CLEAR");
    timer.startTimer("S4_ll_CLEAR");
	llist.clear();
    timer.stopTimer("S4_ll_CLEAR");
    
  }
  
  public boolean canContain(int id) {
    return id<size;
  }
  
  public Collection<PolyAlloy> values() {
    return llist;
  }
  public int getSize() {
    return llist.size();
  }
  
  public String toString() {
    StringBuffer sb = new StringBuffer();
    sb.append("size="+llist.size());
    return sb.toString();
  }
  
  @Override
  public void trunc_and_pack(int new_size, boolean pack) {
    int cnt = 0;
    LinkedList<PolyAlloy> sorted_values = (LinkedList<PolyAlloy>)sorted_values(new_size);

    PolyAlloy last = sorted_values.descendingIterator().next();
    int newmaxdistance = comparator.distance(last.box)+1000;
    Storage4 newset = new Storage4(newmaxdistance, comparator, timer);
	Iterator<PolyAlloy> iter = sorted_values.iterator();
    while (cnt < new_size) {
      if (iter.hasNext()) {
          PolyAlloy next = iter.next();
          if (pack) {
               next.pack();
           }
         newset.add(next);
      }
      cnt++;
    }
    this.llist = newset.llist;
    this.content = newset.content;
    this.size = newset.size;
  }
  @Override
  public Collection<PolyAlloy> sorted_values(int max_count) {
    List<PolyAlloy> res = new LinkedList<PolyAlloy>();
    for (int i = 0; i < content.length; i++) {
      if (content[i]!=null) {
        res.add(content[i]);
      }
      if (res.size()==max_count) break;
    }
    return res;
  }

  
  
}
